const CUP_ARR   = [10, 7, 3];
const INIT_ARR  = [10, 0, 0];
const FINAL_ARR = [5, 5, 0];
const SIDE_ARR = [
  [0, 1],
  [0, 2],
  [1, 0],
  [1, 2],
  [2, 0],
  [2, 1]
]

let count = 0;

function goToNext(nowNode, path = []) {
  for (let i = 0; i < 6; i++) {
    let _path = JSON.parse(JSON.stringify(path));
    try {
      let nextNode = goOneRoad(nowNode, i, _path);
      if (nextNode) {
        _path.push(nextNode);
        if (JSON.stringify(nextNode) === JSON.stringify(FINAL_ARR)) {
          console.log(`Succeed, the final path is ${_path.length}`)
          console.log(_path)
        } else {
          goToNext(nextNode, _path);
        }
      }
    } catch(e) {
      // console.log(e.message, count++);
    }
  }
}

function goOneRoad(nowNode, side, path) {
  // console.log(count++);
  let nextNode = fixCup(nowNode, SIDE_ARR[side][0], SIDE_ARR[side][1]);
  path.forEach(node=>{
    if (JSON.stringify(node) === JSON.stringify(nextNode)) {
      throw new Error(`Throw the repeated node, Die with ${path.length} step` )
    }
  })
  return nextNode;
}

function fixCup(nowNode, from, to) {
  if (from == to) {
    throw new Error('Can not send the water to itself');
  }
  let nextNode = JSON.parse(JSON.stringify(nowNode));

  let fromWater = nowNode[from];
  let toWater = nowNode[to];
  let sumWater = fromWater + toWater;

  let finalToWater = sumWater > CUP_ARR[to] ? CUP_ARR[to] : sumWater;
  let finalFromWater = sumWater - finalToWater;

  nextNode[from] = finalFromWater;
  nextNode[to] = finalToWater;

  return nextNode;
}

goToNext(INIT_ARR, [INIT_ARR])